﻿/*
 * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
 */

#ifndef CHANNEL_H
#define CHANNEL_H

#include "BurnToolCommon/StdAfx.h"
#include "BurnToolCommon/sop_errno.h"
#include "BurnToolCommon/Global.h"
namespace ChannelName {
const unsigned int HI3921_RANDOM_LEN = 192;
#define CHL_PACKET_MIN_LEN (sizeof(CHL_PACKET_DATA_HEAD))
const unsigned int MAX_CHL_DATA_SIZE = 2048;
#define MIN_CHL_HI3921_RANDOM_LEN (HI3921_RANDOM_LEN + CHL_PACKET_MIN_LEN)


#define SEBOOT_ACK_LEN (sizeof(SEBOOT_ACK_FRAME))

const unsigned char CHL_PACKET_START_FLAG = 0xED;
const unsigned char CHL_PACKET_DEFAULT_CS = 0xFF;
const unsigned char CHL_PACKET_END_FLAG = 0xEE;

const int DECODE_PACKET_SUCCSS = 0;
const int DECODE_PACKET_PART = 1;
const int DECODE_PACKET_MORE_THAN_ONE = 2;
const int DECODE_PACKET_ERROR = 3;

const QString CHL_SUCCESS_STR = "SUCCESS";
const QString CHL_FAIL_STR = "FAIL";
const QString CHL_INTERRUPT_FLAG_ROMBOOT = "interrupt #";
const QString CHL_INTERRUPT_FLAG_FLASHBOOT = "interrupt $";
const QString CHL_INTERRUPT_FLAG_COMMON = "interrupt";

const int RESET_FRAME_TYPE_87 = 0x87;
}

using namespace ChannelName;

// 自定义报文交互数据格式（CTRL+C 和 YModem不使用）
struct CHL_PACKET_DATA_HEAD {
    unsigned int startFlag {0};         // 起始符:0xDEADBEEF
    unsigned short packetDataSize {0}; // 帧长：真实传输数据长度，要求最大不超过2048.
    unsigned short cs {0};               // 帧长：传输数据的U16校验和
    unsigned short type {0};
    unsigned short pad {0};
};

struct YMODE_START_END_PACKET {
    unsigned char flag; // 起始符:0x01
    unsigned char packetNum;
    unsigned char packetNumReserve;
    unsigned char data[128]; // 128小包
    unsigned char crc[2];    // crc16 len 2
};

struct YMODE_INFO_PACKET_LARGE {
    unsigned char flag; // 起始符:0x02
    unsigned char packetNum;
    unsigned char packetNumReserve;
    unsigned char data[1024]; // 1024大包
    unsigned char crc[2];     // crc16 len 2
};

struct YMODE_INFO_PACKET_8K {
    unsigned char flag; // 起始符:0x02
    unsigned char packetNum;
    unsigned char packetNumReserve;
    unsigned char data[8192]; // 1024大包
    unsigned char crc[2];     // crc16 len 2
};

struct YMODE_INFO_PACKET_SMALL {
    unsigned char flag; // 起始符:0x02
    unsigned char packetNum;
    unsigned char packetNumReserve;
    unsigned char data[128]; // 128小包
    unsigned char crc[2];    // crc16 len 2
};

struct SEBOOT_SHAKE_HANDS_FRAME {
    unsigned int startFlag;    // 起始符:0xDEADBEEF
    unsigned short packetSize; // 帧长：真实传输数据长度，要求最大不超过2048.
    unsigned char frameType;   // 帧长：传输数据的U16校验和
    unsigned char frameTypeReverse;
    unsigned int baudRate;
    unsigned char dataBits;
    unsigned char stopBits;
    unsigned char parity;
    unsigned char flowctrl;
    unsigned short checkSum;
};

struct SEBOOT_ACK_FRAME {
    unsigned int startFlag;
    unsigned short packetSize;
    unsigned char frameType;
    unsigned char frameTypeReverse;
    unsigned char result;
    unsigned char errorCode;
    unsigned short checkSum;
};

enum HI_RSA_PADDING_MODE {
    HI_MODE_PKCS_PADDING = 0x00,
    HI_MODE_PKCS_PSS = 0x01,
};

enum HI_UART_AUTH_TYPE {
    UART_AUTH_TYPE_RANDOM = 1,
    UART_AUTH_TYPE_CHALLANGE,
    UART_CTRL_B,
    UART_CTRL_C
};

enum HI_UART_AUTH_TYPE_WIFI {
    UART_SHAKE_HANDS = 0xf0,
    UART_ACK_FRAME = 0xE1,
};

struct SIGNATURE_PUBKEY_DATA_HEAD {
    unsigned short signatureLen;       /* *< 签名长度: RSA2048: 256字节 */
    unsigned short pubkeyModulusLen;  /* *< 公钥N长度: RSA2048: 256字节 */
    unsigned short pubkeyExponentLen; /* *< 公钥E长度：0x010001，默认3字节 */
    unsigned char paddingMode;         /* *< 填充方式：HI_RSA_PADDING_MODE */
    unsigned char pad;
};

namespace ChannelClass {
class Channel {
public:
    static unsigned short SopCrc16(const unsigned char *pData, UINT ulSize);
    static int DecodeSEBootAck(const unsigned char *pSrcData,
                               int srcDataLen, SEBOOT_ACK_FRAME &chlPktHead, int &resDataLen);

    static int DecodeYmodeHeadPacket(const unsigned char *pSrcData, int srcDataLen, YMODE_START_END_PACKET &chlPktHead,
        int &resDataLen, U32 &packetSize);
    static int DecodeYmodeLargePacket(const unsigned char *pSrcData,
                                      int srcDataLen, YMODE_INFO_PACKET_LARGE &chlPktHead,
        int &resDataLen);
    static int DecodeYmode8KPacket(const unsigned char *pSrcData, int srcDataLen, YMODE_INFO_PACKET_8K &chlPktHead,
        int &resDataLen);
    static int DecodeYmodeSmallPacket(const unsigned char *pSrcData, int srcDataLen,
                                      YMODE_INFO_PACKET_SMALL &chlPktHead, int &resDataLen);
    static int GetYmodeSTX(int size);

    static unsigned char CalcCheckSum(const unsigned char *pData, unsigned short len);

    static unsigned short CalcCheckSumU16(const unsigned char *pData, int dataLen);
    static uint32_t Crc32Byte(uint32_t accum, uint8_t delta);
private:
    Channel();
    ~Channel();
};
}

struct SEBOOT_DOWNLOAD_FLASHIMAGE {
    unsigned int startFlag;
    unsigned short packetSize;
    unsigned char frameType;
    unsigned char frameTypeReverse;
    unsigned int fileAddr;
    unsigned int fileLen;
    unsigned int eraseSize;
    unsigned char formal;
    unsigned char formalReverse;
    unsigned short checkSum;
    SEBOOT_DOWNLOAD_FLASHIMAGE() : startFlag(Global::chlStartFlag), packetSize(0x18), frameType(0xd2),
        frameTypeReverse(0x2d), fileAddr(0), fileLen(0), eraseSize(0), formal(0), formalReverse(0xff), checkSum(0)
    {
    }
    void GetCrc()
    {
        checkSum = ChannelClass::Channel::SopCrc16(reinterpret_cast<PBYTE>(&startFlag), packetSize - 2); // crc16 len 2
    }
};

struct SEBOOT_DOWNLOAD_OTP_EFUSE {
    unsigned int startFlag;
    unsigned short packetSize;
    unsigned char frameType;
    unsigned char frameTypeReverse;
    unsigned int fileLen;
    unsigned short checkSum;
    SEBOOT_DOWNLOAD_OTP_EFUSE() : startFlag(Global::chlStartFlag),
        packetSize(0x0e), frameType(0xc3), frameTypeReverse(0x3c), fileLen(0), checkSum(0)
    {
    }
    void GetCrc()
    {
        checkSum = ChannelClass::Channel::SopCrc16(reinterpret_cast<PBYTE>(&startFlag), packetSize - 2); // crc16 len 2
    }
};

struct SEBOOT_READ_OTP_EFUSE {
    unsigned int startFlag;
    unsigned short packetSize;
    unsigned char frameType;
    unsigned char frameTypeReverse;
    unsigned short startBit;
    unsigned short bitWidth;
    unsigned short checkSum;
    SEBOOT_READ_OTP_EFUSE() : startFlag(Global::chlStartFlag),
        packetSize(0x0e), frameType(0xa5), frameTypeReverse(0x5a), startBit(0), bitWidth(0), checkSum(0) {}
    void GetCrc()
    {
        checkSum = ChannelClass::Channel::SopCrc16(reinterpret_cast<PBYTE>(&startFlag), packetSize - 2); // crc16 len 2
    }
};

struct SEBOOT_UPLOAD_DATA {
    unsigned int startFlag;
    unsigned short packetSize;
    unsigned char frameType;
    unsigned char frameTypeReverse;
    unsigned int fileLen;
    unsigned int fileAddr;
    unsigned short checkSum;
    SEBOOT_UPLOAD_DATA() : startFlag(Global::chlStartFlag), packetSize(0x12), frameType(0xb4),
        frameTypeReverse(0x4b), fileLen(0), fileAddr(0), checkSum(0)
    {
    }
    void GetCrc()
    {
        checkSum = ChannelClass::Channel::SopCrc16(reinterpret_cast<PBYTE>(&startFlag), packetSize - 2); // crc16 len 2
    }
};

struct SEBOOT_FLASH_LOCK {
    unsigned int startFlag;
    unsigned short packetSize;
    unsigned char frameType;
    unsigned char frameTypeReverse;
    unsigned short param;
    unsigned short checkSum;
    SEBOOT_FLASH_LOCK() : startFlag(Global::chlStartFlag), packetSize(0x0c),
        frameType(0x96), frameTypeReverse(0x69), param(0), checkSum(0)
    {
    }
    void GetCrc()
    {
        checkSum = ChannelClass::Channel::SopCrc16(reinterpret_cast<PBYTE>(&startFlag), packetSize - 2); // crc16 len 2
    }
};

struct SEBOOT_RESET {
    unsigned int startFlag;
    unsigned short packetSize;
    unsigned char frameType;
    unsigned char frameTypeReverse;
    unsigned short param;
    unsigned short checkSum;
    SEBOOT_RESET() : startFlag(Global::chlStartFlag), packetSize(0x0c), frameType(RESET_FRAME_TYPE_87),
        frameTypeReverse(0x78), param(0), checkSum(0)
    {
    }
    void GetCrc()
    {
        checkSum = ChannelClass::Channel::SopCrc16(reinterpret_cast<PBYTE>(&startFlag), packetSize - 2); // crc16 len 2
    }
};

struct SEBOOT_DOWNLOAD_FACTORYBIN {
    unsigned int startFlag;
    unsigned short packetSize;
    unsigned char frameType;
    unsigned char frameTypeReverse;
    unsigned int fileAddr;
    unsigned int fileLen;
    unsigned int eraseSize;
    unsigned char formal;
    unsigned char formalReverse;
    unsigned short checkSum;
    SEBOOT_DOWNLOAD_FACTORYBIN() : startFlag(Global::chlStartFlag), packetSize(0x18), frameType(0x78),
        frameTypeReverse(0x87), fileAddr(0), fileLen(0), eraseSize(0), formal(0), formalReverse(0xff), checkSum(0)
    {
    }
    void GetCrc()
    {
        checkSum = ChannelClass::Channel::SopCrc16(reinterpret_cast<PBYTE>(&startFlag), packetSize - 2); // crc16 len 2
    }
};

struct SEBOOT_DOWNLOAD_VERSION {
    unsigned int startFlag;
    unsigned short packetSize;
    unsigned char frameType;
    unsigned char frameTypeReverse;
    unsigned int fileLen;
    unsigned short checkSum;
    SEBOOT_DOWNLOAD_VERSION() : startFlag(Global::chlStartFlag), packetSize(0x0e), frameType(0x69),
        frameTypeReverse(0x96), fileLen(0), checkSum(0)
    {
    }
    void GetCrc()
    {
        checkSum = ChannelClass::Channel::SopCrc16(reinterpret_cast<PBYTE>(&startFlag), packetSize - 2); // crc16 len 2
    }
};

struct SEBOOT_DOWNLOAD_NV {
    unsigned int startFlag;
    unsigned short packetSize;
    unsigned char frameType;
    unsigned char frameTypeReverse;
    unsigned int fileAddr;
    unsigned int fileLen;
    unsigned int eraseSize;
    unsigned short encItemCnt;
    unsigned short flag;
    unsigned short checkSum;
    SEBOOT_DOWNLOAD_NV() : startFlag(Global::chlStartFlag), packetSize(0x1a), frameType(0x4B),
        frameTypeReverse(0xB4), fileAddr(0), fileLen(0), eraseSize(0), encItemCnt(0), flag(0), checkSum(0)

    {
    }
    void GetCrc()
    {
        checkSum = ChannelClass::Channel::SopCrc16(reinterpret_cast<PBYTE>(&startFlag), packetSize - 2); // crc16 len 2
    }
};

struct SEBOOT_SWITCH_DFU {
    unsigned int startFlag;
    unsigned short packetSize;
    unsigned char frameType;
    unsigned char frameTypeReverse;
    unsigned short flag;
    unsigned short checkSum;
    SEBOOT_SWITCH_DFU() : startFlag(Global::chlStartFlag), packetSize(0xc), frameType(0x1e),
        frameTypeReverse(0xe1), flag(0), checkSum(0) {
    }
    void GetCrc()
    {
        checkSum = ChannelClass::Channel::SopCrc16(reinterpret_cast<PBYTE>(&startFlag), packetSize - 2); // crc16 len 2
    }
};

#endif // CHANNEL_H
